#include "HY1C_out.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "l2_struc.h"
#include "l12_parms.h"

void free_l2( l2str *l2rec )
{
     free((void *) l2rec->data);
}


/* --------------------------------------------------------- */
/* alloc_l2() - allocates 1 level-2 record to hold data for  */
/*              a single scan of "npix" pixels.              */
/* --------------------------------------------------------- */
int alloc_l2( int32_t npix, int32_t nbands, l2str *l2rec )
{
     char *p;
     int32_t len =  3*sizeof(int32_t )
              +  2*sizeof(int32_t )*npix
              +  10*sizeof(float)*npix
              + 14*sizeof(float)*npix*nbands
              +  1*sizeof(int32_t)*npix;

     if (len % 4 != 0)
         len = len / 4 * 4 + 4;

     if ((p = (char *) malloc(len)) == NULL) {
         fHY1C_out(stderr,
             "-E- %s line %d: Memory allocation failure.\n",
             __FILE__,__LINE__);
         return(0);
     }

     l2rec->length = len;
     l2rec->npix   = npix;
     l2rec->data   = p;

     l2rec->year      = (int32_t   *) p;  p += sizeof(int32_t);
     l2rec->day       = (int32_t   *) p;  p += sizeof(int32_t);
     l2rec->msec      = (int32_t   *) p;  p += sizeof(int32_t);
     l2rec->lon       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->lat       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->solz      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->sola      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->senz      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->sena      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->delphi    = (float  *) p;  p += sizeof(float)*npix;
     l2rec->Lt        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Lt_unc    = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->aermodmin = (int32_t   *) p;  p += sizeof(int32_t)*npix;
     l2rec->aermodmax = (int32_t   *) p;  p += sizeof(int32_t)*npix;
     l2rec->aerratio  = (float  *) p;  p += sizeof(float)*npix;
     l2rec->eps       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->taua      = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->TLg       = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->La        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Lw        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->nLw       = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->nLw_unc   = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->brdf      = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Rrs       = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Rrs_unc   = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->a         = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->bb        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Rrc        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->chl       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->num_iter  = (int32_t   *) p;  p += sizeof(int32_t )*npix;

     if ((len - (int32)(p - l2rec->data)) < 0) {
         HY1C_out("%s Line %d: bad allocation on L2 record\n",__FILE__,__LINE__);
         exit(1);
     }

     HY1C_out("Allocated %d bytes in L2 record.\n",(int32)(p - l2rec->data));

     return(len);
}

int alloc_l2_single(int32_t nbands, l2str *l2rec )
{
    int32_t npix = 1;
     char *p;
     int32_t len =  3*sizeof(int32_t )
              +  2*sizeof(int32_t )*npix
              +  12*sizeof(float)*npix
              + 17*sizeof(float)*npix*nbands;

     if (len % 4 != 0)
         len = len / 4 * 4 + 4;

     if ((p = (char *) malloc(len)) == NULL) {
         fHY1C_out(stderr,
             "-E- %s line %d: Memory allocation failure.\n",
             __FILE__,__LINE__);
         return(0);
     }

     l2rec->length = len;
     l2rec->npix   = npix;
     l2rec->data   = p;

     l2rec->year      = (int32_t   *) p;  p += sizeof(int32_t);
     l2rec->day       = (int32_t   *) p;  p += sizeof(int32_t);
     l2rec->msec      = (int32_t   *) p;  p += sizeof(int32_t);
     l2rec->lon       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->lat       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->solz      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->sola      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->senz      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->sena      = (float  *) p;  p += sizeof(float)*npix;
     l2rec->delphi    = (float  *) p;  p += sizeof(float)*npix;
     l2rec->Lt        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Lt_unc    = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->aermodmin = (int32_t   *) p;  p += sizeof(int32_t)*npix;
     l2rec->aermodmax = (int32_t   *) p;  p += sizeof(int32_t)*npix;
     l2rec->aerratio  = (float  *) p;  p += sizeof(float)*npix;
     l2rec->eps       = (float  *) p;  p += sizeof(float)*npix;
     l2rec->taua      = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->TLg       = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->La        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Lw        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Lr        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->tLf        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Lt_theroy        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->tg_sol        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->tg_sen        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->t_sol        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->t_sen        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->gain        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->aot_new      = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->Fo        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->wv        = (float  *) p;  p += sizeof(float)*npix;
     l2rec->Tau_r        = (float  *) p;  p += sizeof(float)*npix*nbands;
     l2rec->rh        = (float  *) p;  p += sizeof(float)*npix;
     l2rec->pr        = (float  *) p;  p += sizeof(float)*npix;
     //l2rec->nLw       = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->nLw_unc   = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->brdf      = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->Rrs       = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->Rrs_unc   = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->a         = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->bb        = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->Rrc        = (float  *) p;  p += sizeof(float)*npix*nbands;
     //l2rec->chl       = (float  *) p;  p += sizeof(float)*npix;
     //l2rec->num_iter  = (int32_t   *) p;  p += sizeof(int32_t )*npix;

     if ((len - (int32_t)(p - l2rec->data)) < 0) {
         HY1C_out("%s Line %d: bad allocation on L2 record\n",__FILE__,__LINE__);
         exit(1);
     }

     HY1C_out("Allocated %d bytes in L2 record.\n",(int32)(p - l2rec->data));

     return(len);
}
